home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
fft.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
301 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* fft -
* simple 2-D fft support
*
* Paul Haeberli - 1990
*/
#include "math.h"
#include "image.h"
#include "fft.h"
imgtocomp(image,comp,size)
IMAGE *image;
complex *comp;
int size;
{
int x, y;
short *row;
row = (short *)malloc(size*sizeof(short));
for(y=0; y<size; y++) {
getrow(image,row,y,0);
for(x=0; x<size; x++) {
comp->r = row[x]/255.0;
comp->i = 0.0;
comp++;
}
}
free(row);
}
zapzero(comp,size)
complex *comp;
int size;
{
int x, y;
for(y=0; y<size; y++) {
for(x=0; x<size; x++) {
if(x == 0 || y == 0) {
comp->r = 0.0;
comp->i = 0.0;
}
comp++;
}
}
}
#define WRAPX(x) (((x)+size/2)%size)
#define WRAPY(y) (((y)+size/2)%size)
ffttoimg(buf,image,size)
complex *buf;
IMAGE *image;
int size;
{
complex *comp;
int x, y;
float min, max, sc, val;
int n, i;
float mag, *mags;
short *row;
n = size*size;
mags = (float *)malloc(n*sizeof(float));
row = (short *)malloc(size*sizeof(short));
max = -100000.0;
min = 100000.0;
comp = buf;
comp->r = 0;
comp->i = 0;
i = 0;
while(n--) {
mag = sqrt(comp->r*comp->r+comp->i*comp->i);
mags[i++] = mag;
if(max<mag)
max = mag;
if(min>mag)
min = mag;
comp++;
}
if(min<0.0)
min = -min;
if(max<0.0)
max = -max;
if(min>max)
max = min;
printf("min max %f %f\n",min,max);
sc = 1.0/max;
comp = buf;
i = 0;
for(y=0; y<size; y++) {
for(x=0; x<size; x++) {
mag = mags[i++];;
row[WRAPX(x)] = 255.0*(mag-min)/(max-min);
comp++;
}
putrow(image,row,WRAPY(y),0);
}
free(row);
free(mags);
}
complex *compalloc(n)
int n;
{
return (complex *)malloc(n*sizeof(complex));
}
fftrange(comp,n,min,max)
complex *comp;
int n;
double *min, *max;
{
*max = -100000.0;
*min = 100000.0;
while(n--) {
if(comp->r > *max)
*max = comp->r;
if(comp->r < *min)
*min = comp->r;
comp++;
}
}
comptoimg(comp,image,size)
complex *comp;
IMAGE *image;
int size;
{
int x, y;
double min, max;
short *row;
row = (short *)malloc(size*sizeof(short));
fftrange(comp,size*size,&min,&max);
printf("final img range: %f %f\n",min,max);
for(y=0; y<size; y++) {
for(x=0; x<size; x++) {
row[x] = 255.0*comp->r;
if(row[x]>255)
row[x]=255;
if(row[x]<0)
row[x]=0;
comp++;
}
putrow(image,row,y,0);
}
free(row);
}
printcomp(comp,size)
complex *comp;
int size;
{
int x, y;
for(y=0; y<size; y++) {
for(x=0; x<size; x++) {
if(comp->r != 0.0 || comp->i != 0.0)
printf("at %d %d: %f %f\n",x,y,comp->r,comp->i);
comp++;
}
}
}
fft2(n,isign,din,dout)
int n, isign;
complex *din;
complex *dout;
{
int y;
for(y=0; y<n; y++)
fft(n,isign,din+(y*n));
ffttranspose(n,din,dout);
for(y=0; y<n; y++)
fft(n,isign,dout+(y*n));
}
ffttranspose(n,din,dout)
int n;
complex *din;
complex *dout;
{
int x, y;
complex *sptr, *dptr;
sptr = din;
for(y=0; y<n; y++) {
dptr = dout+y;
for(x=0; x<n; x++) {
*dptr = *sptr++;
dptr += n;
}
}
}
fft(n,isign,data)
int n, isign;
complex data[];
{
int i;
int j, k, ln, nv2;
complex temp, u, w;
int le, le1,l;
powercheck(n);
if(isign>0)
isign = 1;
else
isign = -1;
for(ln=0, i=n; i>1; i>>=1)
ln++;
nv2 = n/2;
j=0;
n--;
for(i=0; i<n; i++) {
if(i<j) {
temp = data[j];
data[j] = data[i];
data[i] = temp;
}
k = nv2;
while(j>=k) {
j -= k;
k >>= 1;
}
j += k;
}
n++;
le = 2;
le1 = 1;
for(l=0; l<ln; l++) {
double tempr, tempi;
double ur, ui;
double wr, wi;
complex *ipptr, *iptr;
ur = 1.0;
ui = 0.0;
wr = cos(isign*3.1415926535/le1);
wi = -sin(isign*3.1415926535/le1);
for(j=0; j<le1; j++) {
for(i=j; i<n; i+=le) {
iptr = data+i;
ipptr = iptr+le1;
tempr = ur*ipptr->r - ui*ipptr->i;
tempi = ur*ipptr->i + ui*ipptr->r;
ipptr->r = iptr->r - tempr;
ipptr->i = iptr->i - tempi;
iptr->r += tempr;
iptr->i += tempi;
}
tempr = ur;
ur = wr*ur - wi*ui;
ui = wr*ui + wi*tempr;
}
le <<= 1;
le1 <<= 1;
}
if(isign == 1) {
for(i=0; i<n; i++) {
data[i].r /= n;
data[i].i /= n;
}
}
}
powercheck(n)
int n;
{
int i;
for(i=0; i<32; i++) {
if(n&1)
break;
n >>= 1;
}
if(n != 1) {
fprintf(stderr,"fft: n points must be a power of 2!!\n");
exit(1);
}
}